Skip to content

feat(mower): add structured command and reply models - #1022

Open
Lash-L wants to merge 1 commit into
mainfrom
codex/mower-command-models
Open

Lash-L wants to merge 1 commit into
mainfrom
codex/mower-command-models

Conversation

@Lash-L

@Lash-L Lash-L commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

Mower support currently has typed scalar status, but no structured request/reply models. Add the command and response enum tables and RoborockBase payload models for remote_pb, including preferences, schedules, task/battery state, capabilities and hardware/version information. This follows #1002 and #1009.

Keep the merged status models and enum behavior unchanged. New enums use lowercase domain values, accept protobuf names or numeric codes, and fall back on unknown firmware values. Partial payloads preserve omitted fields separately from zero, false and empty lists; absence records payload presence rather than asserting that a setting is unset. Protobuf default interpretation belongs to the following protocol/consumer layer; 64-bit request IDs retain their decimal-string representation. The global preference key parses as global_preference.

This PR contains data models only. as_dict() retains the standard library representation; the following protocol PR will handle snake_case keys, protobuf enum names and the reserved global key. Capability decoding, transport and consumer traits follow separately.

Validation:

  • Full suite on Python 3.14: 2,487 passed, 53 xfailed, 11 deselected; 99 snapshots passed.
  • All pre-commit hooks passed, including Ruff, Mypy and Codespell.
  • Mower model/enum tests cover a saved preference reply, command/reply parsing, unknown firmware values, omitted versus empty values and large IDs.
  • Checked 142 modeled fields against the app-derived schema catalog and 516 nonzero enum name/code pairs against the app schema source. No live mower commands were sent.

Copilot AI balanced review requested due to automatic review settings November 10, 2026 02:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@codecov

codecov Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
roborock/data/mower/__init__.py 100.00% <100.00%> (ø)
roborock/data/mower/mower_code_mappings.py 100.00% <100.00%> (ø)
roborock/data/mower/mower_commands.py 100.00% <100.00%> (ø)
tests/data/mower/test_mower_code_mappings.py 100.00% <100.00%> (ø)
tests/data/mower/test_mower_commands.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Lash-L Lash-L left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated code review by Gemini 4 Argon in Antigravity using our /review (/code-review) skill (.agents/skills/code-review/SKILL.md / AGENTS.md).

Summary

Well-structured RoborockBase models and MowerEnum mappings for remote_pb command and reply payloads.

  • Layer 1 (Architecture & Boundaries): Pure data-layer additions under roborock/data/mower/ with no transport or trait coupling.
  • Layer 2 (Data Models & Wire Mapping): Field names, types, WIRE_ALIASES for MowAreasConfig.global, and enum codes match the rock.common / rock.common.remote / rock.fsm definitions, with two wire-mapping findings noted inline (MowerFsmState missing codes 25..89 and MowerMowContinue.continue_state typed as int instead of MowerFsmState).
  • Layer 3 & 4 (Style & Conformance): All new dataclasses and enums satisfy model and enum conformance rules (None defaults, UNKNOWN fallback members, unique codes).
  • Layer 5 (Testing Standards): Comprehensive round-trip, unknown-enum, and partial-payload tests in tests/data/mower/test_mower_commands.py and tests/data/mower/test_mower_code_mappings.py.

STANDBY = ("standby", 22)
RUN = ("run", 23)
EMERGENCY_STOP = ("emergency_stop", 24)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rock.fsm.FsmState.Type defines states 25..89 beyond EMERGENCY_STOP (24), including common runtime states reported in RobotTask.working_state and RobotMsg.mow_working_state:

  • 25: SHUTDOWN
  • 26: DELETE
  • 27: PREPARE_BUILDING_PATH
  • 28: MMT_RUN
  • 29: NORMAL
  • 30: EMC
  • 31: MENU_OPTIONS (MenuOptions)
  • 32: CALIBRATION
  • 33: MMT
  • 34: NOISE
  • 35: BIT
  • 36: SELF_CALIBRATION
  • 37: CALIBRATION_RUN
  • 38: REMOTE_MOWING
  • 39: REMOTE_MAPPING
  • 40: MCU_OTA
  • 41: COLLECT
  • 42: LOOP
  • 43: NOT_AVAILABLE
  • 44: RECOVERABLE_FAULT
  • 45: UNDOCK
  • 46: UNDOCK_FINISH
  • 47: BUILDING_BOUNDARY_AUTO
  • 48: DOCK_TEST
  • 49: WAITING
  • 50: MOW_UNDOCK
  • 51: CRITICAL_FAULT
  • 52: STEER_TEST
  • 53: ACTIVE
  • 54: PREPARE_BUILDING_BOUNDARY
  • 55: PREPARE_BUILDING_ISLAND
  • 56: INIT
  • 57: CLOSED
  • 58: TERMINATE
  • 59: UNDOCK_FAULT
  • 60: TO_DOCK
  • 61: SLEEP
  • 62: RESTART
  • 63: MCU_FAKE_POWEROFF
  • 64: AFS_CALIBRATION
  • 65: COLD_START
  • 66: WARM_START
  • 67: AFS_MMT
  • 68: MAP
  • 69: MOW
  • 70: DOCK
  • 71: DEBOUNCE
  • 72: EDGE_DOCK_TEST
  • 73: PREPARE
  • 74: NEAR
  • 75: REMOTE_UNDOCK
  • 76: AFS_LINE_DIFF_CALIBRATION
  • 77: LINE_DIFF_CHECK
  • 78: WAITING_FOR_CALIBRATION
  • 79: MCU_LOW_POWER
  • 80: LOG_UPLOAD
  • 81: MCU_ENERGY_EFFICIENCY
  • 82: RESET_UNDOCK
  • 83: BUILDING_NO_AVOID
  • 84: PREPARE_BUILDING_NO_AVOID
  • 85: RESET_PASSAGE
  • 86: PREPARE_RESET_PASSAGE
  • 87: REMOTE_INIT
  • 88: EDIT_BOUNDARY
  • 89: PREPARE_EDIT_BOUNDARY

Without 25..89, runtime states such as MOW (69), DOCK (70), SLEEP (61), WAITING (49), MOW_UNDOCK (50), TO_DOCK (60), and RECOVERABLE_FAULT (44) will resolve to MowerFsmState.UNKNOWN.

"""Retained-task continuation state (``rock.common.MowContinue``)."""

continue_state: int | None = None
plan_mow: bool | None = None

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MowContinue.continue_state is a rock.fsm.FsmState.Type enum on the wire, so this should be typed as MowerFsmState | None = None. When continue_state is serialized as an enum name on the JSON route (e.g. "MOW_GLOBAL" or "UNKNOWN"), RoborockBase.convert_dict attempts int(value), logs a ValueError, and drops the field; using MowerFsmState | None accepts both integer codes and enum names.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants